using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;

using Enums = PHSRAG.Security.Enumerations;
using PHSRAG.Insight21.Context;

namespace PHSRAG.Insight21.InsightWebControls
{
	/// <summary>
	/// Summary description for AdminHumansSubNavigation.
	/// </summary>
	[ToolboxData("<{0}:AdminHumansSubNavigation runat=server />")]
	[Designer(typeof(AdminUserManagementSubNavigationDesigner), typeof(IDesigner))]
	public class AdminHumansSubNavigation : SubNavigation
	{
		#region Constants
		private const string SelectedAdminHumansSubNavigationLinkKey = "SelectedAdminHumansManagementSubNavigationLink_B48E6BE0-AC86-4d16-92A8-FD33CFF06CC6";
		private const string NavigateCommand = "Navigate";
		#endregion

		#region Instance Variables
		private LinkButton formsManagementLinkButton;
		private LinkButton workFlowManagerLinkButton;
		private LinkButton workFlowAdminLinkButton;
		private LinkButton workFlowErrorAdminLinkButton;
		private LinkButton listManagementLinkButton;

		private	Policy.ICachePolicy	cachePolicy;
		
		#endregion

		/// <summary>
		/// Determines if the Forms Management tab should be visible (i.e. if the user is a System Administrator
		/// or a Forms Manager
		/// </summary>
		private bool IsFormsManagementVisible
		{
			get 
			{
				return 
					((((UserContext)cachePolicy.GetCachedObject(UserContext.CacheKey)).ModuleRoleBitmask & 
					((int)Enums.ModuleRoleBit.SystemAdministrator | (int)Enums.ModuleRoleBit.FormsManager)) != 0);
			}
		}

		/// <summary>
		/// Determines if the Workflow Management tab should be visible (i.e. if the user is a System Administrator
		/// or a Workflow Manager
		/// </summary>
		private bool IsWorkflowManagementVisible
		{
			get 
			{
				return 
					((((UserContext)cachePolicy.GetCachedObject(UserContext.CacheKey)).ModuleRoleBitmask & 
					((int)Enums.ModuleRoleBit.SystemAdministrator | (int)Enums.ModuleRoleBit.WorkflowManager)) != 0);
			}
		}

		/// <summary>
		/// Determines if the List Management tab should be visible (i.e. if the user is a System Administrator
		/// or a List Manager
		/// </summary>
		private bool IsListManagementVisibile
		{
			get 
			{
				return 
					((((UserContext)cachePolicy.GetCachedObject(UserContext.CacheKey)).ModuleRoleBitmask & 
					((int)Enums.ModuleRoleBit.SystemAdministrator | (int)Enums.ModuleRoleBit.ListManager)) != 0);
			}
		}

		#region Private Properties
		/// <summary>
		/// Return true if the control is in design mode.
		/// </summary>
		private static bool IsDesignMode
		{
			get { return HttpContext.Current == null; }
		}
		#endregion

		#region Implementations for abstract properties and methods from Base Class SubNavigation

		/// <summary>
		/// Handler for the event raised when the page is being initialized.
		/// Retrieve the cache policy and page cache policy in force.
		/// </summary>
		/// <param name="e">Argument associated with the event</param>
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
			if (!IsDesignMode)
			{
				cachePolicy = (Policy.ICachePolicy)Page.Session[Policy.Names.CachePolicyKey];
			}
		}

		/// <summary>
		/// Create all controls in the AdminUserManagementSubNavigation, depending on user's roles
		/// </summary>
		protected override void CreateControls()
		{
			Controls.Clear();

			if (IsFormsManagementVisible)
			{
				formsManagementLinkButton = new LinkButton();
				formsManagementLinkButton.CommandName = formsManagementLinkButton.Text = "Forms Management";
				formsManagementLinkButton.CommandArgument = Utility.Settings.GetKeyValue("SubNavigation.Admin.Humans.FormsManagementURL", "");
			}

			if (IsWorkflowManagementVisible)
			{
				workFlowManagerLinkButton = new LinkButton();
				workFlowManagerLinkButton.CommandName = workFlowManagerLinkButton.Text = "Workflow Management";
				workFlowManagerLinkButton.CommandArgument = Utility.Settings.GetKeyValue("SubNavigation.Admin.Humans.WorkFlowManagerURL", "");	
		
				workFlowAdminLinkButton = new LinkButton();
				workFlowAdminLinkButton.CommandName = workFlowAdminLinkButton.Text = "Workflow Admin Activity";
				workFlowAdminLinkButton.CommandArgument = Utility.Settings.GetKeyValue("SubNavigation.Admin.Humans.WorkFlowAdminURL", "");	

				workFlowErrorAdminLinkButton = new LinkButton();
				workFlowErrorAdminLinkButton.CommandName = workFlowErrorAdminLinkButton.Text = "Workflow Errors";
				workFlowErrorAdminLinkButton.CommandArgument = Utility.Settings.GetKeyValue("SubNavigation.Admin.Humans.WorkFlowErrorURL", "");	
			}

			if (IsListManagementVisibile)
			{
				listManagementLinkButton = new LinkButton();
				listManagementLinkButton.CommandName = listManagementLinkButton.Text = "Data Management";
				listManagementLinkButton.CommandArgument = Utility.Settings.GetKeyValue("SubNavigation.Admin.Humans.ListRequestURL", "");
			}
		}

		/// <summary>
		/// Setup the control tree to reflect the actual (and exact) layout of the controls within the AdminUserManagementSubNavigation.
		/// </summary>
		protected override void GenerateControlTree()
		{
			
			Table table = new Table();
			Controls.Add(table);
			table.CssClass = "SubModuleSummaryNavigation";

			TableRow row = new TableRow();
			table.Rows.Add(row);

			TableCell cell = new TableCell();
			row.Cells.Add(cell);
			cell.CssClass = "SubModuleSummaryNavigationFillerCell";
			cell.Controls.Add(new LiteralControl("&nbsp;"));

			cell = new TableCell();
			row.Cells.Add(cell);

			table = new Table();
			cell.Controls.Add(table);

			row = new TableRow();
			table.Rows.Add(row);

			cell = new TableCell();
			row.Cells.Add(cell);

			if (IsFormsManagementVisible)
			{
				cell = new TableCell();
				row.Cells.Add(cell);
				cell.Controls.Add(formsManagementLinkButton);
			}

			if (IsWorkflowManagementVisible)
			{
				cell = new TableCell();
				row.Cells.Add(cell);
				cell.Controls.Add(workFlowManagerLinkButton);

				cell = new TableCell();
				row.Cells.Add(cell);
				cell.Controls.Add(workFlowAdminLinkButton);

				cell = new TableCell();
				row.Cells.Add(cell);
				cell.Controls.Add(workFlowErrorAdminLinkButton);
			}

			if (IsListManagementVisibile)
			{
				cell = new TableCell();
				row.Cells.Add(cell);
				cell.Controls.Add(listManagementLinkButton);				
			}
            CreateSelectedLinkAdornments(row);
		}

		/// <summary>
		/// The selected link cell is given a prefix and suffix image as adornments. In addition the background of the
		/// cell is of a different style.
		/// </summary>
		private void CreateSelectedLinkAdornments(TableRow row)
		{
			LinkButton selectedLink = GetSelectedLink();
			if (selectedLink != null)
			{
				foreach (TableCell cell in row.Cells)
				{
					if ((cell.Controls.Count == 1) && (cell.Controls[0] == selectedLink))
					{
						cell.CssClass = "SubModuleNavigationSelectedSummary";

						TableCell adornmentCell = new TableCell();
						adornmentCell.CssClass = "SubModuleNavigationSelectedSummaryAdornment";
						row.Cells.AddAt(row.Cells.GetCellIndex(cell), adornmentCell);

						const string prefixImage = "../Images/Row2_Left.gif";
						System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(Context.Server.MapPath(prefixImage));
						Image image = new Image();
						image.ImageUrl = prefixImage;
						adornmentCell.Width = bitmap.Width;
						adornmentCell.Controls.Add(image);

						adornmentCell = new TableCell();
						adornmentCell.CssClass = "SubModuleNavigationSelectedSummaryAdornment";
						row.Cells.AddAt(row.Cells.GetCellIndex(cell) + 1, adornmentCell);

						const string suffixImage = "../Images/Row2_Right.gif";
						bitmap = new System.Drawing.Bitmap(Context.Server.MapPath(suffixImage));
						image = new System.Web.UI.WebControls.Image();
						image.ImageUrl = suffixImage;
						adornmentCell.Width = bitmap.Width;
						adornmentCell.Controls.Add(image);

						break;
					}
				}
			}
		}

		/// <summary>
		/// Retrieve the name of the link that was last clicked on.
		/// </summary>
		/// <returns>Reference to the link button corresponding to the clicked link</returns>
		protected override LinkButton GetSelectedLink()
		{
			// Anytime a link is clicked on, the OnBubbleEvent handler stores the name of the link in the session. Retrieve
			// that name and return the corresponding link button reference.

			object o = Page.Session[SelectedAdminHumansSubNavigationLinkKey];
			if (o != null)
			{
				string commandName = (string)o;
				if (formsManagementLinkButton != null && commandName == formsManagementLinkButton.CommandName)
					return formsManagementLinkButton;
				if (workFlowManagerLinkButton != null && commandName == workFlowManagerLinkButton.CommandName)
					return workFlowManagerLinkButton;	
				if (workFlowAdminLinkButton != null && commandName == workFlowAdminLinkButton.CommandName)
					return workFlowAdminLinkButton;
				if (workFlowErrorAdminLinkButton != null && commandName == workFlowErrorAdminLinkButton.CommandName)
					return workFlowErrorAdminLinkButton;
				if (listManagementLinkButton != null && commandName == listManagementLinkButton.CommandName)
					return listManagementLinkButton;	
			}
			return formsManagementLinkButton;
		}
		
		/// <summary>
		/// 
		/// </summary>
		protected override string SelectedSubNavigationLinkKey
		{
			get 
			{
				return SelectedAdminHumansSubNavigationLinkKey;
			}
		}

        /// <summary>
        /// Set the selected link so that on load, the appropriate tab may be shown highlighted. This property is invoked
        /// by pages while vectoring to other pages which host this navigation control.
        /// </summary>
        public string SelectedLink
        {
            set { Page.Session[SelectedSubNavigationLinkKey] = value; }
        }
		/// <summary>
		/// Delegate used by page to be informed of navigation event
		/// </summary>
		public delegate void NavigateEventHandler();

		/// <summary>
		/// Add/remove a handler for the "Navigate to new page" command
		/// </summary>
		public new event NavigateEventHandler Navigate
		{
			add		{ Events.AddHandler(NavigateCommand, value); }
			remove	{ Events.RemoveHandler(NavigateCommand, value); }
		}

		/// <summary>
		/// Notifies NavigateEventHandlers if navigation is occurring, and makes a call
		/// to the base method
		/// </summary>
		/// <param name="source"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		protected override bool OnBubbleEvent(object source, EventArgs args)
		{
			if ((args is CommandEventArgs) && (source is LinkButton))
			{
				NavigateEventHandler handler = (NavigateEventHandler)Events[NavigateCommand];
				if (handler != null)
					handler();					
			}

			return base.OnBubbleEvent (source, args);
		}

		#region Event Handlers
		/// <summary>
		/// Disable view state.
		/// </summary>
		/// <param name="e">Argument associated with the load event.</param>
		protected override void OnLoad(EventArgs e)
		{
			EnableViewState = false;
			base.OnLoad (e);	
		}
		#endregion

		#endregion

	}
	
	#region Class AdminHumansSubNavigationDesigner 
	/// <summary>
	/// Designer associated with the control.
	/// </summary>
	public class AdminHumansSubNavigationDesigner : ControlDesigner
	{
		#region Overrides
		/// <summary>
		/// Force the control to create its child controls for display at design time.
		/// </summary>
		/// <returns>HTML representation of the control</returns>
		public override string GetDesignTimeHtml()
		{
			((AdminHumansSubNavigation)Component).Design();
			return base.GetDesignTimeHtml();
		}
		#endregion
	}
	#endregion
}
